local skynet = require "skynet"
local util = require "util"
local zjh = require "zhajinhua.czjh"
local table_unpack = table.unpack
local table_insert = table.insert
local table_remove = table.remove
local math_random = math.random

local M = {}

local Methods = {}
local MT = {
    __index = Methods
}

function M.new(uid,player_info,robot_type,AI,addr,fd,pattern)
    local o = {
        uid = uid,
        player_info = player_info,
        AI = AI,
        addr = addr,
        fd = fd,
        robot_type = robot_type,
        table_pattern = pattern,
    }

    return setmetatable(o, MT)
end

function Methods:on_register(uid)
    if uid ~= self.uid then
        return
    end
--    print("Methods:on_register",self.fd)
    self.is_exit = false

    local rob_info = {
        client_version  = '',
        channel         = '',
        cur_channel     = '',
        device_id       = '',
        device_brand    = '',
    }
    skynet.send(self.addr,'lua','enter',self.uid,self.fd,rob_info)
end

--自己进桌
function Methods:on_enter()
    return
end

function Methods:system_win_robot()
    self.system_win = true
end

local function analyse_play(self)
    if not self.zjh_instance:is_started() then
        return
    end
    print("analyse_play",self.zjh_instance:get_next_player_uid(),self.uid)
    if self.zjh_instance:get_next_player_uid() == self.uid and self.zjh_instance:player_isvalid(self.uid) then
        self.play_time = util.get_now_time() + math_random(3,5)
        self.req_msg_list = self.AI.analyse_play(self)
        print("self.req_msg_list",tostring_r(self.req_msg_list))
    end
end

local function look_analyse_play(self)
    if not self.zjh_instance:is_started() then
        return
    end
   -- print("look_analyse_play",self.zjh_instance:get_next_player_uid(),self.uid)
    if self.zjh_instance:get_next_player_uid() == self.uid and self.zjh_instance:player_isvalid(self.uid) then
        self.play_time = util.get_now_time() + math_random(3,5)
        self.req_msg_list = self.AI.look_analyse_play(self)
       -- print("self.req_msg_list",tostring_r(self.req_msg_list))
    end
end

--游戏开始触发
function Methods:on_start(zjh_instance)
    self.zjh_instance = zjh_instance
    self.weight = 0
end

function Methods:on_start_play()
 --   dbglog('on_start_play')
    analyse_play(self)
end

--出牌
function Methods:on_play(uid)
    dbglog(uid,'on_play ....',self.uid)
    if uid ~= self.uid then return end
    analyse_play(self)
end


function Methods:on_look_card(uid)
    --dbglog(uid,'on_look_card ....')
    if uid ~= self.uid then return end
    look_analyse_play(self)
end

function Methods:on_add_socre(uid,add_type)
    local zjh_instance = self.zjh_instance
    if not zjh_instance then return end
    --每次玩家进行加注,设置该轮已经有玩家加注，其他机器人不能加注
    if add_type == 1 then


        self.zjh_instance:set_jiazhu_record(self.uid)

    end

end

function Methods:judge_use_pic(curr_time)
    --上一次发表情的时间间隔小于1s，先不发，避免两个表情同步
    if self.last_pic_time and curr_time - self.last_pic_time < 1 then
        return
    end

    local picture_list = self.picture_list
    if picture_list then
        if #picture_list > 2 then
            table_remove(self.picture_list,1)
        end
        for k = #picture_list,1,-1 do
            local pic_info = picture_list[k]
            if curr_time > pic_info.send_time then
                skynet.send(self.addr,'lua','REQ_CHAT',self.uid,pic_info.msg,self.fd)
                table_remove(self.picture_list,k)
                self.last_pic_time = curr_time
                return
            end
        end
    end
end

--机器人使用表情
function Methods:on_use_picture(uid,pic_conf,is_enter)
    if self.uid ~= uid then return end
    if not pic_conf then
        print(uid,"=====pic_conf is nil ===")
        return
    end 
 
    local select_pic,delay_time
    if self.zjh_instance then
        select_pic,delay_time = self.zjh_instance:robot_can_use_pic(pic_conf)
    elseif is_enter or not self.zjh_instance then    --玩家刚进来时instance可能未初始化,结算时instance已置nil
        if math_random(1,100) <= pic_conf.use_rate then
            local use_pic,delay_time = pic_conf.select_pic 
            select_pic = use_pic[math_random(1,#use_pic)]
            if pic_conf.delay_time and pic_conf.delay_time[1] and pic_conf.delay_time[2]then
                delay_time = math_random(pic_conf.delay_time[1],pic_conf.delay_time[2])
            end
        end 
    end
    if select_pic then
        if not delay_time or delay_time < 2 then 
            delay_time = math_random(2,3)     --至少给个2s种的延时吧
        end
        local msg = {
            type = 1,
            picture_id = select_pic,
        }
        if not self.picture_list then
            self.picture_list = {}
        end
        table_insert(self.picture_list,{
            send_time = util.get_now_time() + delay_time,--每个动作之后，过两秒再发，避免动作和表情包同步，太假
            msg = msg
        }) 
        if self.zjh_instance then
            self.zjh_instance:add_use_pic_num()
        end
    end
end

--游戏结束
function Methods:on_game_over()
    self.zjh_instance = nil
    self.game_status = nil
    self.will_give_up = false
    self.weight = 0
    self.add_flag = false
    --self.picture_list = nil
    self.last_pic_time = nil
    
    --清楚上一局的扎金花策略
    self.genzhu_limit = nil
    self.compare = nil
    self.analyse_logic = nil
    self.genzhu = nil
    self.bet_limit = nil
    self.limit_action = nil
    self.system_win = nil
end


function Methods:ntf_player_operate_status(msg)
    local zjh_instance = self.zjh_instance
    if not zjh_instance then
        return
    end
    if not zjh_instance:is_started() then
        return
    end
    if not zjh_instance:player_isvalid(self.uid) then
        return
    end
    self.game_status = nil
    self.game_status = msg.buttons_status
    --print("Methods:ntf_player_operate_status",tostring_r(self.game_status))
end

function Methods:on_leave_now(uid)
    if self.uid == uid then
        skynet.send(self.addr,'lua',"REQ_LEAVE",self.uid,{},self.fd)
    end
end

--机器人选择的比牌对象
local function get_compare_des_uid(self)
    --1.优先选择已看牌的玩家
    --2.在看牌的玩家中优先选择被动比牌并且胜利的玩家(被动比牌:其他玩家主动跟你比牌,你即为被动比牌),如果存在多个此类玩家随机一个选择比牌。
    --3.如果没有被动比牌并胜出的玩家，则优先选择最后一个看牌加注的玩家
    --4.如果没有看牌加注的玩家，选择最后一个进行看牌跟注的玩家
    --5.如果无已看牌玩家，则优先选择最后一个焖牌加注的玩家
    --6.如果无焖牌加注的玩家，则随机选择一个玩家  
    --7.排除自己
    local zjh_instance = self.zjh_instance
    zjh_instance:update_robot_compare_list(self.uid)
    local win_list = zjh_instance:get_ming_win_list()
    if #win_list > 0 then
        local uid = win_list[math_random(1,#win_list)]
        if uid ~= self.uid then return uid end 
    end

    local record_last_score = zjh_instance:get_ming_score_record()
    if record_last_score[1] then     
        local uid = record_last_score[1]
        if uid ~= self.uid then return uid end 
    end
    if record_last_score[2] then  
        local uid = record_last_score[2]--2、明牌跟注；
        if uid ~= self.uid then return uid end 
    end
    if record_last_score[3] then 
        local uid = record_last_score[3]       --3、焖牌加注
        if uid ~= self.uid then return uid end 
    end
    
    local ming_list = zjh_instance:get_valid_ming_player(self.uid)
    if #ming_list > 0 then
        local uid = ming_list[math_random(1,#ming_list)]
        if uid ~= self.uid then return uid end 
    end

    return zjh_instance:get_random_uid(self.uid)
end

function Methods:update_play(curr_time)

    local zjh_instance = self.zjh_instance
    if not zjh_instance then
        return
    end

    if not zjh_instance:is_started() then
        return
    end


    --轮到自己出牌
    if zjh_instance:get_next_player_uid() == self.uid and 
        zjh_instance:player_isvalid(self.uid) and
        self.play_time and curr_time >= self.play_time then
        if self.req_msg_list then
            for _, req_msg in pairs(self.req_msg_list) do
                --如果是比牌策略，这里再确定到底要跟谁进行比牌
                if req_msg.pb_name == 'REQ_COMPARE_CARD' and zjh_instance:get_left_num() > 1 then
                    --local dst_uid = zjh_instance:get_best_card_set(self.uid)
                    local dst_uid = get_compare_des_uid(self)
                    --print("========compare_uid===",dst_uid,self.uid)
                    -- assert(dst_uid,"dst_uid==nil")
                    req_msg.msg = {dst_uid = dst_uid} 
                elseif req_msg.pb_name == 'REQ_COMPARE_BEST_CARD' then
                    local dst_uid = zjh_instance:get_best_card_uid_other(self.uid)
                    req_msg.pb_name = 'REQ_COMPARE_CARD'
                    req_msg.msg = {dst_uid = dst_uid}
                end
                --dbglog(self.uid,req_msg.pb_name,req_msg.msg)
                skynet.send(self.addr,'lua',req_msg.pb_name,self.uid,req_msg.msg,self.fd)  
            end
        end

        self.play_request = nil
        self.play_time = nil
    end
end

function Methods:update()
    while not self.is_exit do
        self:judge_use_pic(util.get_now_time())

        if not self.zjh_instance then
            skynet.sleep(50)    --500ms
            goto continue
        end

        --判断当前游戏结束的话就continue掉 不在处理机器人后续的协议
        if self.zjh_instance:is_game_over() then
            skynet.sleep(50)    --500ms
            goto continue
        end

        local curr_time = util.get_now_time()

        self:update_play(curr_time)

        skynet.sleep(50)    --500ms
        ::continue::
    end
end

function Methods:on_exit()
    self.is_exit = true
    R().robotmgr(1):send('.msg_handler','put_back_robots',{{type=self.robot_type,uid=self.uid,coins=self.player_info.coins}})
end

return M